<?php
/**
 * Created by PhpStorm.
 * User: xiaomeng
 * Date: 17-7-13
 * Time: 上午10:23
 */
namespace swf\socket;

use swf\common\Bet;
use swf\common\ToBet;
use swf\common\User;
use swf\common\Utils;
use swf\core\syncDb;

class Task
{
    static private $allow_cmd = ['open','broadcastMsg','openRecord','bet','prize','betRefund','init','sendMsg','balance','tobet','toprize'];
    static private $server;

    /**
     * 根据任务命令执行命令
     * @param $server
     * @param $task_id
     * @param $src_worker_id
     * @param $data
     */


    static public function run($server, $task_id,$src_worker_id,$data)
    {
//        usleep(100);
        self::$server = $server;
        //解析data
        $data = json_decode($data,true);
        //判断命令是否存在
        if(!in_array($data['cmd'],self::$allow_cmd))
        {
            return false;
        }

        $func = $data['cmd'];
        self::$func($data['data']);

        return true;


    }

    /**
     * 开奖
     * @param $data
     */
    static public function open($data)
    {
        $open = OpenNum::run();
        syncDb::redis()->set('open_num',$data.'_'.$open['open_num'].'_'.$open['open_deg']);
        //开奖记录
        $time = time();
        $year = date('Y',$time);
        syncDb::mysql()->insert('open_record_'.$year,[
            'no_id'=>$data,
            'open_num'=>$open['open_num'],
            'created_at'=>$time,
            'open_type'=>$open['open_type'],
            'open_index'=>$open['open_index'],
        ]);
        return;
    }

    /**
     * 广播消息
     * @param $data
     */

    static public function broadcastMsg($data)
    {
        $cmd = $data['send_cmd'];
        $data = $data['send_data'];
        foreach (self::$server->connections as $fd)
        {
            Response::send(self::$server,$fd,$cmd,$data);
        }
        return;
    }

    /**
     * 更新历史记录15旗
     * @param $data
     */
    static public function openRecord($data)
    {
        $time = time();
        $year = date('Y',$time);
        $_res = syncDb::mysql()->select('open_record_'.$year,['open_num'],["LIMIT"=>15,"ORDER"=>["created_at"=>"DESC"]]);
        $res = array_column($_res,"open_num");
        syncDb::redis()->set('open_record',json_encode($res));
        return;
    }

    /**
     * 投注
     * @param $data
     */
    static public function bet($data)
    {
        $fd = $data['fd'];
        //获取用户信息
        $user_info = OperaFd::getUserInfo($fd);
        $channel_id = $user_info['channelId'];
        $userId = $user_info['userId'];
        $roomId = $user_info['roomId'];
        $betting_num = $data['betting_num'];
        $amount = $data['amount'];
        //旗号 游戏状态
        $game_status = syncDb::redis()->get('game_status');
        $game_status = json_decode($game_status,true);
        if($game_status['game_status']['open_status'] != 1)
        {
            Response::send(self::$server,$fd,'error',[],11);
            return true;
        }
        //限投
        $_res = LimitBet::upperLimit($betting_num,$amount);

        if($_res === false)
        {
            Response::send(self::$server,$fd,'error',[],15);
            return true;
        }

        $time = time();
        $gameSetId = $game_status['game_status']['no_id'];
        //写入数据库
            $_insert = [
                "no_id"=>$gameSetId,
                "member_id"=>$userId,
                "betting_num"=>$betting_num,
                "betting_money"=>$amount,
                "channel_id"=>$channel_id,
                "room_id"=>$roomId,
                "bet_status"=>1,
                "prize_money"=>0,
                "day"=>date('d',$time),
                "month"=>date('m',$time),
                "created_at"=>$time
            ];
            $res = syncDb::mysql()->insert("betting_record_".date('Y',$time),$_insert);
            if(empty($res))
            {
                Response::send(self::$server,$fd,'error',[],12);
            } else {
                //房间投注详情
                $betInfo = OperaBet::addBet($roomId,$betting_num,$amount,$gameSetId);
                Response::send(self::$server,$fd,'bet',['betting_num'=>$betting_num,'betting_money'=>$amount,'betInfo'=>$betInfo],0);
                $fds = OperaFd::getRoomOtherFdByRoomId($channel_id,$roomId,$fd);
                Response::sendAll(self::$server,'betInfo',$fds,$betInfo,0);
            }
        return true;
    }

    /**
     * prize($gameSetId,$orderId,$userId,$amount,$operationTime,$description)
     * */
    static public function prize($data)
    {
        //根据游戏局号和渠道号，进行派奖
        $channel_id = $data['channel_id'];
        $open_num = $data['open_num'];
        $no_id = $data['no_id'];
        $time = time();
        $table = "betting_record_".date('Y',$time);
        $res = syncDb::mysql()->select($table,[
            "id",
            "member_id",
            "betting_money",
        ],[
            "bet_status"=>1,
            "no_id"=>$no_id,
            "betting_num"=>$open_num,
            "channel_id"=>$channel_id
        ]);
        //统计用户消息
        if(!empty($res))
        {
            $groupMsg = [];
            //章鱼
            foreach($res as $k=>&$v)
            {
                $v['prize_money'] = (int)$open_num * $v['betting_money'];
                @$groupMsg[$v['member_id']] +=$v['prize_money'];//用户赢的总额
            }
            //自己
            foreach($res as $v1)
            {
                syncDb::mysql()->update($table,[
                    "bet_status"=>2,
                    "prize_money"=>$v1['prize_money'],
                    "updated_at"=>$time,
                ],[
                    "id"=>$v1['id']
                ]);
            }
            //群发中奖消息
            //1.获取渠道下所有的人员信息
            $fds = OperaFd::getChannelFds($channel_id);
            Response::sendAll(self::$server,'prize',$fds,['prizeInfo'=>$groupMsg],0);
        }
        return true;

    }




    /**
     * 投注撤销
     * @param $data
     */
    static public function betRefund($data)
    {
        $fd = $data['fd'];
        //获取用户信息
        $user_info = OperaFd::getUserInfo($fd);
        $channel_id = $user_info['channelId'];
        $userId = $user_info['userId'];
        $roomId = $user_info['roomId'];
        //旗号 游戏状态
        $game_status = syncDb::redis()->get('game_status');
        $game_status = json_decode($game_status,true);
        if($game_status['game_status']['open_status'] != 1)
        {
            Response::send(self::$server,$fd,'error',[],13);
            return true;
        }
        $gameSetId = $game_status['game_status']['no_id'];
        $time = time();
        //取出用户投注的订单
        $table = "betting_record_".date('Y',$time);

        $res = syncDb::mysql()->select($table,["id","betting_num","betting_money","is_sum","sum_order_id"],[
            "no_id"=>$gameSetId,
            "member_id"=>$userId,
            "channel_id"=>$channel_id,
            "bet_status"=>1,
            "is_sum"=>[0,1],//全部的撤销
        ]);
        if(empty($res))
        {
            Response::send(self::$server,$fd,'error',[],14);
            return true;
        }
        $del_bet = [];//需要取消的投注
        foreach ($res as $k=>$v)
        {
            @$del_bet[$v['betting_num']] += $v['betting_money'];
        }
        $order_ids = array_column($res,"id");
        $_res = syncDb::mysql()->update($table,[
                    "bet_status"=>3,
                    "cancel_at"=>$time
                ],[
                    "id"=>$order_ids
                ]);
        if(empty($_res))
        {
            Response::send(self::$server,$fd,'error',[],17);
            return true;
        }
        //房间投注详情
        $betInfo = OperaBet::delBet($roomId,$del_bet,$gameSetId);
        Response::send(self::$server,$fd,'betRefund',['del_bet'=>$del_bet,'betInfo'=>$betInfo],0);
            //群发
        $fds = OperaFd::getRoomOtherFdByRoomId($channel_id,$roomId,$fd);
        Response::sendAll(self::$server,'betInfo',$fds,$betInfo,0);
        //退出的撤销
        $toBetRefund = [];
        foreach ($res as $v)
        {
            if($v['is_sum'] == 1)
            {
                $toBetRefund[] = $v['sum_order_id'];
            }
        }
        if(!empty($toBetRefund))
        {
            self::toBetRefund($toBetRefund);
        }
        return true;
    }

    /**
     * 向房间群发聊天信息
     * @param $data
     * @return bool
     */
    static public function sendMsg($data)
        {
            $fd = $data['fd'];
            $sendData = $data['sendMsg'];
            //判断用户所在的房间
            $fds = OperaFd::getRoomFd($fd);
            $fds = array_merge($fds['user'],$fds['observer']);
            //
            $user_info = OperaFd::getUserInfo($fd);
            $sendData['from'] = $user_info['userId'];
            //向房间群发
            Response::sendAll(self::$server,'receiveMsg',$fds,$sendData,0);
            return true;
        }

    /**
     * 生成订单ID
     * @return string
     */
    static private function creatOrderId()
    {
        $order_id = Utils::create_uuid();
        $year = date('Y',time());
        $res = syncDb::mysql()->count("betting_record_".$year,[
            "order_id"=>$order_id
        ]);
        if(!empty($res))
        {
            self::creatOrderId();
        }
        return $order_id;

    }

    /**
     * 初始化
     * @return mixed
     */
    static public function init($data)
    {
        /*******************************************/
        $userId = $data['userId'];//后期去掉
        /******************************************/
        $fd = $data['fd'];
        $userOpenId = $data['userOpenId'];
        $token = $data['token'];
        $channelId = $data['channelId'];
        $type = $data['type'];
        //不能重复初始化
        if(OperaFd::isInit($fd))
        {
            Response::send(self::$server,$fd,'error',[],9);
            return true;
        }
        //人员判断
        $bet = new Bet();
        /******************************************************/
        //后期打开
//        $userId = $bet->token($userOpenId,$token);
//        $userId = $userId['userId'];
        /****************************************************/
        //判断用户是否已经登录
        $setUsetRes = OperaFd::setUserIdList($userId,$fd);
        if($setUsetRes === false)
        {
            Response::send(self::$server,$fd,'error',[],4);
            return true;
        }
        //
//        OperaFd::setUserFd($userId,$fd);//设置对应表
        $_user = new User();
        $_user_info = $_user->getUserInfo($userId);
        $nickName = isset($_user_info['name'])?$_user_info['name']:'';
        $tel = isset($_user_info['phone'])?$_user_info['phone']:'';
        $ico = isset($_user_info['ico'])?$_user_info['ico']:'';
        //渠道判断
        $channelData = syncDb::mysql()->select("channel",[
            'channel_id','shop_name','logo','bg_img'
        ],[
            "is_usable"=>1,
            "channel_id"=>$channelId,
            "LIMIT"=>1
        ]);
        $channelData = $channelData[0];
        if(empty($channelData))
        {
            Response::send(self::$server,$fd,'error',[],7);
            return true;
        }
        //用户类型判断
        if(!in_array($type,['user','observer']))
        {
            Response::send(self::$server,$fd,'error',[],6);
            return true;
        }
        //根据渠道ID分配房间
        $res = OperaFd::save($fd,$userId,$nickName,$tel,$ico,$channelId,$type);
        if($res === false)
        {
            Response::send(self::$server,$fd,'error',[],8);
            return true;
        }
        //获取用户余额
        $money_data = $bet->balance($userId);
        $money_data = (float)$money_data['balance'];
        //近15期开奖结果
        $open_history = syncDb::redis()->get('open_record');
        //旗号 倒计时
        $game_status = syncDb::redis()->get('game_status');
        $game_status = json_decode($game_status,true);
        $no_id = $game_status['game_status']['no_id'];
        //获取房间其他成员信息
        $roomFds = OperaFd::getRoomFd($fd);
        $roomFds = $roomFds['user'];
        $roomUserInfo = OperaFd::getUsersInfo($roomFds);
        //获取用户所在房间的投注详情
        $user_info = OperaFd::getUserInfo($fd);
        $roomId = $user_info['roomId'];
        $bet_info = OperaBet::getRoomBet($roomId);
        //获取用户上一次本房间投注情况
        $user_bet = syncDb::mysql()->select("betting_record_".date('Y',time()),[
            'betting_num',
            'betting_money'
        ],[
            'no_id'=>$no_id,
            'room_id'=>$roomId,
            'bet_status'=>1,
        ]);
        $_user_bet = [];
        if(!empty($user_bet))
        {
            foreach($user_bet as $v)
            {
                @$_user_bet[$v['betting_num']] += $v['betting_money'];
            }

        }


        //返回数据
        $data = [
            'userId'=>$userId,
            'type'=>$type,
            'room_shop_name'=>$channelData['shop_name'],
            'logo'=>$channelData['logo'],
            'bg_img'=>$channelData['bg_img'],
            'balance'=>$money_data,
            'open_history'=>json_decode($open_history,true),
            'sy_time'=>$game_status['sy_time'],
            'open_status'=>$game_status['game_status']['open_status'],
            'no_id'=>$no_id,
            'roomUserInfo'=>$roomUserInfo,
            'bet_info'=>$bet_info,
            'user_bet'=>$_user_bet,

        ];
        //自己
        Response::send(self::$server,$fd,'init',$data,0);
        //房间其他人
        $_data = [
            "userId"=>$userId,
            "nickName"=>$nickName,
            "tel"=>$tel,
            "ico"=>$ico
        ];
        $fds = OperaFd::getRoomOtherFd($fd);
        Response::sendAll(self::$server,'onlineNotice',$fds,$_data,0);
        return true;


    }


    /**
     * 查询余额
     * @param $data
     * @return bool
     */
    static public function balance($data){
        $fd = $data['fd'];
        //获取用户ID
        $_userInfo = OperaFd::getUserInfo($fd);
        $userId = $_userInfo['userId'];

        $bet = new Bet();
        $res = $bet->balance($userId);//获取趣币余额

        if($res !== false)
        {
            Response::send(self::$server,$fd,'balance',['balance'=>$res['balance']],0);
        } else {
            Response::send(self::$server,$fd,'error',[],16);
        }
        return true;
    }

    /**
     * 投注派奖
     * @param $data
     * @return bool
     */
    static public function tobet($data)
    {
        //向章鱼请求
        $toBet = new ToBet();
        $toBet->bet($data['noId'],$data['userId']);
        return true;
    }

    static public function toprize($data)
    {
        //向章鱼请求
        $toBet = new ToBet();
        $toBet->offlinePrize($data['noId']);
        return true;
    }

    static public function toBetRefund($data)
    {
        //向章鱼请求
        $toBet = new ToBet();
        $toBet->offlineBetRefund(urlencode(json_encode($data)));
        return true;
    }



}